#include "NetGame.h"

NetGame::NetGame()
{
    _socket = NULL;
    _bSide=false;
    QString token = Login::Token;
    globalToken = token;
    qDebug()<<"TOKEN:"<<token;
    wsUrl="ws://"+Login::BaseIP+":"+Login::BasePort+"/ws?token="+token;
    _ptimer = new QTimer;
    //开始连接服务器
    _socket = new QWebSocket();
    connect(_socket,SIGNAL(disconnected()),this,SLOT(onDisconnected()),Qt::AutoConnection);
    connect(_socket,SIGNAL(textMessageReceived(QString)),this,SLOT(onTextReceived(QString)),Qt::AutoConnection);
    connect(_socket,SIGNAL(connected()),this,SLOT(onConnected()),Qt::AutoConnection);
    connect(_ptimer,SIGNAL(timeout()),this,SLOT(reconnect()),Qt::AutoConnection);
    _socket->open(QUrl(wsUrl));
    _socket->ping();
//    qLog(wsUrl);

    //显示执棋
//    showButton();

    //初始化按钮
    startButton->setEnabled(false);
    startButton->setStyleSheet("border:1px solid gray;font: 14pt \"楷体\";color: gray;font-weight: bold;border-image: url(:/img/btn-bg.png);");

}

//断开连接会触发这个槽函数
void NetGame::onDisconnected()
{
    _ptimer->start(3000);
    qLog("系统:准备重画棋盘");
//    qLog("系统:正在连接服务器");
    qDebug()<<("websocket is disconnected");
}
//连接成功会触发这个槽函数
void NetGame::onConnected()
{
    _ptimer->stop();
    qLog("系统:重画成功");
//    qLog("系统:连接服务器成功");
    startButton->setEnabled(true);
    startButton->setStyleSheet("border:1px solid gray;font: 14pt \"楷体\";color: rgb(85, 255, 0);font-weight: bold;border-image: url(:/img/btn-bg.png);");
    qDebug()<<("connect successful");
}
//收到服务发来的消息会触发这个槽函数
void NetGame::onTextReceived(QString msg)
{
    qDebug()<<("textReceiveString" + msg);
    //解析消息
    QJsonParseError *error=new QJsonParseError;
    QJsonDocument doc = QJsonDocument::fromJson(msg.toUtf8(),error);
    if(error->error!=QJsonParseError::NoError)
    {
        qDebug()<<"parseJson:"<<error->errorString();
        return;
    }
    QJsonObject obj = doc.object();
    int cmd = obj["cmd"].toInt();
    if(cmd==0){
        //心跳检测,发送pong
        QJsonObject obj;
        obj.insert("token",globalToken);
        obj.insert("cmd",0);
        QJsonDocument doc;
        doc.setObject(obj);
        QByteArray data = doc.toJson();
        _socket->sendBinaryMessage(data);
    }else if(cmd==1){
        //收到匹配成功信息
        int dstId=obj["dstId"].toInt();
        bool isRed=obj["isRed"].toBool();
        if(dstId!=0){
            //匹配成功
            qLog("系统:匹配成功,开始游戏!");
            isStart=true;
            qDebug()<<isRed;
            _bSide=!isRed;
            if(_bSide==true){
                for(int i=0; i<32; ++i)
                {
                    _p[i].rotate();
                }
            }
        }
        //刷新界面
        update();
    }else if(cmd==2){
        //收到点击信息
        int row = obj["row"].toInt();
        int col = obj["col"].toInt();
        int id = obj["id"].toInt();
        Board::click(id,row,col);
    }else if(cmd==10){
        QString content = obj["content"].toString();
        QString username = obj["dstUsername"].toString();
        addMsg(username +":"+content);
        isPlaySound(content);
    }else if(cmd==20){
        QString content = obj["content"].toString();
        QString username = obj["dstUsername"].toString();
        addMsg(username +":"+content);
        if(content=="请求悔棋"){
            QMessageBox::StandardButton btn;
            btn = QMessageBox::question(this, "提示", "同意 "+username+" 悔棋吗?", QMessageBox::Yes|QMessageBox::No);
            //发送数据
            QJsonObject obj,cobj;
            obj.insert("cmd",20);
            obj.insert("token",globalToken);
            if (btn == QMessageBox::Yes) {
                obj.insert("content","同意悔棋");
            }else{
                obj.insert("content","拒绝悔棋");
            }
            QJsonDocument doc;
            doc.setObject(obj);
            QByteArray data=doc.toJson();
            _socket->sendBinaryMessage(data);
        }else if(content=="同意悔棋"){
            regretPiece();
        }
        //isPlaySound(content);
    }


}
//断开连接会启动定时器，触发这个槽函数重新连接
void NetGame::reconnect()
{
    qLog("系统:重画棋盘");
//    qLog("重新连接服务器");
    qDebug()<<("websocket reconnected");
    _socket->abort();
    _socket->open(QUrl(wsUrl));
}
void NetGame::StartClick()
{
    qLog("系统:开始匹配玩家");
    startButton->setEnabled(false);
    startButton->setStyleSheet("border:1px solid gray;font: 14pt \"楷体\";color: gray;font-weight: bold;border-image: url(:/img/btn-bg.png);");
    qDebug()<<"重写开始游戏"<<isStart;
    //判断选择是否执黑棋
//    _bSide=false;
//    if(!holdCheckBox->isChecked()){
//        _bSide=true;
//        for(int i=0; i<32; ++i)
//        {
//            _p[i].rotate();
//        }
//    }
    //默认为系统匹配对手
    //向服务器发送开始匹配信息
    QJsonObject obj;
    obj.insert("token",globalToken);
    obj.insert("cmd",1);
    QJsonDocument doc;
    doc.setObject(obj);
    QByteArray data = doc.toJson();
    _socket->sendBinaryMessage(data);

    //执黑棋
    update();
}
void NetGame::showButton()
{
    holdCheckBox = new QCheckBox("执红棋",this);
    holdCheckBox->move(625,165);
    holdCheckBox->setChecked(true);
    startButton->setText("开始匹配");
}
void NetGame::click(int id, int row, int col)
{
    //判断是否是自己点击
    if(_selectid==-1 && id!=-1){
        if(_p[id]._red==_bSide){
            return;
        }
    }

    //防止在未到自己下棋时点击
    if(_bRedRun==_bSide){
        return;
    }

    Board::click(id,row,col);
    //发送数据
    QJsonObject obj,cobj;
    obj.insert("cmd",2);
    obj.insert("token",globalToken);
    cobj.insert("row",9-row);
    cobj.insert("col",8-col);
    cobj.insert("id",id);
    obj.insert("click",cobj);

    QJsonDocument doc;
    doc.setObject(obj);
    QByteArray data=doc.toJson();
    _socket->sendBinaryMessage(data);
}

void NetGame::closeEvent ( QCloseEvent * e )
{
    _socket->close();
    qDebug()<<"关闭窗口";

}
void NetGame::sendMsg()
{
    //发送数据
    QJsonObject obj,cobj;
    obj.insert("cmd",10);
    obj.insert("token",globalToken);
    obj.insert("content",chatLine->text());

    QJsonDocument doc;
    doc.setObject(obj);
    QByteArray data=doc.toJson();
    _socket->sendBinaryMessage(data);
    //end
    Board::sendMsg();
}
//快捷消息双击
void NetGame::quickDoubleClicked(const QModelIndex &index)
{
    QString text=quickList.at(index.row());
    text=text.mid(2,text.size()-2);
    if(text.at(0)=='.')
    {
        text=text.mid(1,text.size()-1);
    }
    //发送数据
    QJsonObject obj,cobj;
    obj.insert("cmd",10);
    obj.insert("token",globalToken);
    obj.insert("content",text);

    QJsonDocument doc;
    doc.setObject(obj);
    QByteArray data=doc.toJson();
    _socket->sendBinaryMessage(data);
    addMsg("我:"+text);
}
void NetGame::RegretClick()
{
    regretButton->setEnabled(false);
    qLog("系统:请等待对手是否同意悔棋");
    //发送数据
    QJsonObject obj,cobj;
    obj.insert("cmd",20);
    obj.insert("token",globalToken);
    obj.insert("content","请求悔棋");
    QJsonDocument doc;
    doc.setObject(obj);
    QByteArray data=doc.toJson();
    _socket->sendBinaryMessage(data);
    return;
}
void NetGame::regretPiece()
{
    qLog("系统:开始悔棋");
    if(regretSteps.size()<2){
        qLog("系统:没有棋可悔");
        return;
    }
    //取出步数
    Step *step;
    step = regretSteps.back();
    regretSteps.removeLast();
    //复活棋子
    revivePiece(step->_killid);
    movePiece(step->_moveid,step->_rowfrom,step->_colfrom);
    qDebug()<<"悔棋"<<step->_moveid<<"吃"<<step->_killid<<"row from"<<step->_rowfrom<<"col from"<<step->_colfrom<<"row to"<<step->_rowto<<"col to"<<step->_colto;
    step = regretSteps.back();
    regretSteps.removeLast();
    //复活棋子
    revivePiece(step->_killid);
    movePiece(step->_moveid,step->_rowfrom,step->_colfrom);
    update();
}
